package com.dandelion.api.controller;

import com.dandelion.api.service.InMemoryDictDataScheduledService;
import com.dandelion.common.domain.*;
import com.dandelion.common.service.DictDataService;
import com.google.common.collect.Lists;
import com.rockit.core.pojo.JsonResult;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/dict")
public class DictDataRestController extends BaseRestController {
    private static final Logger logger = LoggerFactory.getLogger(DictDataRestController.class);

    @Resource
    private DictDataService dictDataService;

    @Resource
    private InMemoryDictDataScheduledService inMemoryDictDataScheduledService;

    @RequestMapping("/addr/list")
    public JsonResult getAreaListByCityCode(String parentCode) {
        String _parentCode = StringUtils.isBlank(parentCode) ? DictDataService.PROV_PARENT_CODE : parentCode;
        List<AddressTreeVO> resultList = dictDataService.getAddressList(_parentCode);
        return ok(resultList);
    }

    @RequestMapping("/addr/cascade")
    public JsonResult getAreaListCascadeByCityCode(String parentCode, String column, String name) {
        String _parentCode = StringUtils.isBlank(parentCode) ? DictDataService.PROV_PARENT_CODE : parentCode;
        List<List<AddressTreeVO>> cascadeList = new ArrayList<>(4);
        List<AddressTreeVO> resultList;
        do {
            resultList = dictDataService.getAddressList(_parentCode);
            if (CollectionUtils.isEmpty(resultList)) {
                break;
            }
            cascadeList.add(resultList);
            _parentCode = resultList.get(0).getCode();
        } while (true);
        if (StringUtils.isBlank(parentCode) || DictDataService.PROV_PARENT_CODE.equals(parentCode)) {
            AddressTreeVO first = cascadeList.get(0).get(0);
            if (AddressTreeVO.isDirectProvince(first.getCode()) && cascadeList.size() == 3) {
                cascadeList.add(1, Lists.newArrayList(first));
            }
        } else {
            int _column = NumberUtils.toInt(column);
            if (_column == 2 && cascadeList.isEmpty()) {
                cascadeList.add(Lists.newArrayList(AddressTreeVO.EMPTY));
            } else if (_column == 0 && AddressTreeVO.isDirectProvince(parentCode)) {
                cascadeList.add(0, Lists.newArrayList(AddressTreeVO.toDirectProvince(parentCode)));
            }
        }
        return ok(cascadeList);
    }

    @RequestMapping("/cat/list")
    public JsonResult getCategoryList(Integer parentId) {
        String pid = parentId == null ? "0" : parentId.toString();
        List<CategoryVO> children = inMemoryDictDataScheduledService.getCategoryByParentId(pid);
        if (CollectionUtils.isNotEmpty(children)) {
            List<CategoryWrapperVO> wrapperVOList =
                    children.stream()
                            .map(CategoryWrapperVO::new)
                            .collect(Collectors.toList());
            return ok(wrapperVOList);
        }
        return ok(Lists.newArrayList());
    }

    @RequestMapping("/cat/tree")
    public JsonResult getCategoryCascade(String parentId) {
        String pid = StringUtils.isBlank(parentId) ? "0" : parentId;
        List<CategoryVO> childrenLvl = inMemoryDictDataScheduledService.getCategoryByParentId(pid);
        return ok(childrenLvl);
    }

    @RequestMapping("/cat/svr/tree")
    public JsonResult getTopAndSvrList(Integer parentId) {
        List<CategoryServiceRelationVO> resultList = inMemoryDictDataScheduledService.getTopCatAndSvrList();
        return ok(resultList);
    }

    @RequestMapping("/svr/list")
    public JsonResult getServiceTypeByCategoryId(Integer topCatId) {
        Assert.isTrue(topCatId != null && topCatId > 0, "topCatId is required");
        List<CustomServiceVO> resultList = dictDataService.getCustomServiceByTopCategoryId(topCatId);
        return ok(resultList);
    }

    @RequestMapping("/expr/com/list")
    public JsonResult getExprCompanyList() {
        List<ExpressComponayVO> resultList = dictDataService.getExprCompanyList();
        return ok(resultList);
    }

    @RequestMapping("/reload")
    public JsonResult reload() {
        inMemoryDictDataScheduledService.reload();
        return ok();
    }
}
